<template>
  <div class="webrtc-container">
    <div class="controls">
      <button @click="startLocalStream" :disabled="localStreamActive">获取本地视频</button>
      <button @click="connectWithSDP" >连接</button>
      <button @click="hangUp" :disabled="!isConnected">挂断</button>
    </div>
    
    <div class="video-area">
      <div class="video-box">
        <h2>本地视频</h2>
        <video ref="localVideo" autoplay playsinline muted></video>
      </div>
      <div class="video-box">
        <h2>远程视频</h2>
        <video ref="remoteVideo" autoplay playsinline></video>
      </div>
    </div>
    
    <div class="sdp-area">
      <h2>SDP 交换</h2>
      <textarea 
        v-model="sdpInput" 
        placeholder="在此粘贴远程SDP (Offer/Answer)"
        rows="10"
      ></textarea>
      
      <div v-if="localDescription" class="sdp-display">
        <h3>本地生成的SDP:</h3>
        <pre>{{ localDescription }}</pre>
        <button @click="copySDP" v-if="localDescription">复制SDP</button>
      </div>
    </div>
    
    <div class="status">
      <p>状态: <strong>{{ connectionStatus }}</strong></p>
    </div>
  </div>
</template>

<script>
import { ref, onBeforeUnmount } from 'vue';

export default {
  setup() {
    // DOM 引用
    const localVideo = ref(null);
    const remoteVideo = ref(null);
    
    // 状态和数据
    const sdpInput = ref('');
    const localDescription = ref('');
    const connectionStatus = ref('未连接');
    const localStreamActive = ref(false);
    const isConnected = ref(false);
    
    // WebRTC 相关变量
    let localStream = null;
    let peerConnection = null;

    // 1. 获取本地视频流
    const startLocalStream = async () => {
      try {
        localStream = await navigator.mediaDevices.getUserMedia({
          video: true,
          audio: false
        });
        localVideo.value.srcObject = localStream;
        localStreamActive.value = true;
        connectionStatus.value = '已获取本地视频';
      } catch (err) {
        console.error('获取媒体设备失败:', err);
        connectionStatus.value = '获取视频失败: ' + err.message;
      }
    };

    // 2. 使用输入的SDP建立连接
    const connectWithSDP = async () => {
      if (!sdpInput.value.trim()) {
        alert('请输入有效的SDP');
        return;
      }

      try {
        // 解析输入的SDP
        const sdp = JSON.parse(sdpInput.value.trim());
        
        // 初始化PeerConnection
        peerConnection = new RTCPeerConnection();
        
        // 设置ICE候选处理
        peerConnection.onicecandidate = (event) => {
          if (event.candidate) {
            console.log('ICE Candidate:', event.candidate);
          }
        };
        
        // 设置远程视频流处理
        peerConnection.ontrack = (event) => {
          if (event.streams && event.streams[0]) {
            remoteVideo.value.srcObject = event.streams[0];
            isConnected.value = true;
            connectionStatus.value = '已连接';
          }
        };
        
        // 添加本地轨道（如果是发起方）
        if (localStream) {
          localStream.getTracks().forEach(track => {
            peerConnection.addTrack(track, localStream);
          });
        }
        
        // 判断是Offer还是Answer
        if (sdp.type === 'offer') {
          // 作为接收方处理Offer
          await handleRemoteOffer(sdp);
        } else if (sdp.type === 'answer') {
          // 作为发起方处理Answer
          await handleRemoteAnswer(sdp);
        } else {
          throw new Error('无效的SDP类型');
        }
        
      } catch (err) {
        console.error('SDP处理失败:', err);
        connectionStatus.value = '连接失败: ' + err.message;
        hangUp();
      }
    };

    // 处理远程Offer
    const handleRemoteOffer = async (offer) => {
      try {
        // 设置远程描述
        await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
        connectionStatus.value = '收到Offer，创建Answer...';
        
        // 创建Answer
        const answer = await peerConnection.createAnswer();
        await peerConnection.setLocalDescription(answer);
        
        // 保存生成的Answer供用户复制
        localDescription.value = JSON.stringify(answer, null, 2);
        connectionStatus.value = '已创建Answer，请复制给对方';
        
      } catch (error) {
        console.log("error:",error);
        
        throw error;
      }
    };

    // 处理远程Answer
    const handleRemoteAnswer = async (answer) => {
      try {
        // 设置远程描述
        await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
        connectionStatus.value = '收到Answer，连接建立中...';
        
      } catch (error) {
        console.log("error:",error);
        throw error;
      }
    };

    // 3. 挂断连接
    const hangUp = () => {
      if (peerConnection) {
        peerConnection.close();
        peerConnection = null;
      }
      
      if (remoteVideo.value?.srcObject) {
        remoteVideo.value.srcObject.getTracks().forEach(track => track.stop());
        remoteVideo.value.srcObject = null;
      }
      
      localDescription.value = '';
      isConnected.value = false;
      connectionStatus.value = '已断开连接';
    };

    // 复制SDP到剪贴板
    const copySDP = () => {
      navigator.clipboard.writeText(localDescription.value)
        .then(() => alert('SDP已复制到剪贴板'))
        .catch(err => console.error('复制失败:', err));
    };

    // 组件卸载时清理
    onBeforeUnmount(() => {
      hangUp();
      if (localStream) {
        localStream.getTracks().forEach(track => track.stop());
        localStream = null;
      }
    });

    return {
      localVideo,
      remoteVideo,
      sdpInput,
      localDescription,
      connectionStatus,
      localStreamActive,
      isConnected,
      startLocalStream,
      connectWithSDP,
      hangUp,
      copySDP
    };
  }
};
</script>

<style scoped>
.webrtc-container {
  font-family: Arial, sans-serif;
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px;
}

.controls {
  margin-bottom: 20px;
}

button {
  margin-right: 10px;
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

button:hover:not(:disabled) {
  background-color: #45a049;
}

.video-area {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.video-box {
  flex: 1;
  min-width: 300px;
}

video {
  background: #222;
  width: 100%;
  height: 240px;
  border-radius: 4px;
  margin-bottom: 10px;
}

.sdp-area {
  margin-bottom: 20px;
}

textarea {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-family: monospace;
  margin-bottom: 10px;
  min-height: 150px;
}

.sdp-display {
  background: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  margin-top: 10px;
}

.sdp-display pre {
  white-space: pre-wrap;
  word-wrap: break-word;
}

.status {
  padding: 10px;
  background: #f0f8ff;
  border-radius: 4px;
}

h2, h3 {
  margin: 0 0 10px 0;
  color: #333;
}

@media (max-width: 768px) {
  .video-area {
    flex-direction: column;
  }
}
</style>